﻿using System;
using System.Reflection;
using System.Threading.Tasks;
using Codeflows.Results;
using Codeflows.Tracking;

namespace Codeflows.Dispatch
{
    class AsyncActionMethod : ActionMethodDescriptor
    {
        public AsyncActionMethod(MethodInfo methodInfo, Func<Codeflow, ActionContext, Task<Result>> callsite)
            : base(methodInfo)
        {
            if (callsite == null) throw new ArgumentNullException("callsite");
            Callsite = callsite;
        }

        public override Result ExecuteAction(Codeflow instance, CodeflowInstance codeflowInstance)
        {
            try
            {
                var context = new ActionContext(codeflowInstance);
                return new PendingResult(Callsite(instance, context));
            }
            catch (Exception e)
            {
                if (DiagnosticsUtility.IsFatal(e))
                    throw;

                return new SuspendedResult(e);
            }
        }

        public Func<Codeflow, ActionContext, Task<Result>> Callsite { get; private set; }
    }
}
